﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using Nsf.Samples.RetryActivitySample.Client;
using Nsf.Samples.RetryActivitySample.Infrastructure.Actions;
using Nsf.Samples.RetryActivitySample.Infrastructure.Common.Commands;
using Nsf.Samples.RetryActivitySample.Infrastructure.Common.FaultDetails;
using Nsf.Samples.RetryActivitySample.Infrastructure.Utils;

namespace Nsf.Samples.RetryActivitySample.ServiceTest.Actions
{
    [Action(Name = "Update 'SomeValue' property", Description = "Updates value of the 'SomeValue' property.")]
    public class UpdateSomeValueWorkflowPropertyAction : ActionBase
    {
        private const String WF_INSTANCE_ID = "InstanceId";
        private const String WF_PROPERTY_VALUE = "Value";
        private const String WF_PROPERTY_NAME = "SomeValue";

        protected override ICollection<string> GetKnownArguments()
        {
            var knownArguments = base.GetKnownArguments();
            knownArguments.Add(WF_INSTANCE_ID);
            knownArguments.Add(WF_PROPERTY_VALUE);
            return knownArguments;
        }

        protected override void ValidateArguments(IDictionary<string, string> args)
        {
            String instanceId;
            if (!args.TryGetValue(WF_INSTANCE_ID, out instanceId))
                throw new ValidationException("Argument '{0}' doesn't specified.", WF_INSTANCE_ID);
            if (instanceId.Count() == 0)
                throw new ValidationException("Value of the '{0}' doesn't specified.", WF_INSTANCE_ID);
            var res = instanceId.ToGuid();
            if (res == Guid.Empty)
                throw new ValidationException("'{0}' is invalid uuid.", instanceId);
            String propertyValue;
            if (!args.TryGetValue(WF_PROPERTY_VALUE, out propertyValue))
                throw new ValidationException("Argument '{0}' doesn't specified.", WF_PROPERTY_VALUE);
            if (propertyValue.Count() == 0)
                throw new ValidationException("Value of the '{0}' doesn't specified.", WF_PROPERTY_VALUE);

            Int32 newValue;
            if (!Int32.TryParse(propertyValue, out newValue))
                throw new ValidationException("'{0}' is invalid integer value.");
        }

        protected override void OnExecute(IDictionary<string, string> args)
        {
            using (var client = new WorkflowManagerClient())
            {
                var workflowInstanceId = args[WF_INSTANCE_ID].ToGuid();
                var propertyValue = Int32.Parse(args[WF_PROPERTY_VALUE]);
                var commandData = new SetPropertyValueCommandData() {PropertyName = WF_PROPERTY_NAME, Value = propertyValue};
                client.SendCommandToWorkflow(workflowInstanceId, commandData);
                Console.WriteLine("Value of the 'SomeValue' property was updated.");
            }
        }

        protected override void OnHelp()
        {
            throw new NotImplementedException();
        }
    }
}
